CFPH = {}
CFPH.Draw = {}

CFPH.Draw.paper = null;
CFPH.Draw.listener = null;
CFPH.Draw.outSelected; //[serviceName, rect]
//CFPH.Draw.connections = []; // [[fromServiceName, toServiceName, paramName, outRect, inRect, path], ... ]
CFPH.Draw.services = {}; // {serviceName -> serviceObject}
// serviceObject:
//   
CFPH.Draw.connections = {}; // [[from, to, param] -> connectionObject]

CFPH.Draw.init = function(paper) {
	CFPH.Draw.paper = paper;
}

CFPH.Draw.clear = function() {
//	CFPH.Draw.paper.clear();
}

CFPH.Draw.connectionExists = function(outRect, inRect) {
	var connections = CFPH.Draw.connections;
	
	for (var i=0; i<connections.length; i++) {
		var outI = connections[i][3];
		var inI = connections[i][4];
		
		if ((outI == outRect) && (inI == inRect))
			return true;
	}
	
	return false;
}

CFPH.Draw.addConnection = function(fromServiceName, toServiceName, paramName, outRect, inRect) {
	CFPH.Draw.connections.push([fromServiceName, toServiceName, paramName, outRect, inRect, null]);

	if (CFPH.Draw.listener)
		CFPH.Draw.listener.connectionAdded(outRect.serviceObj, inRect.serviceObj, paramName, [fromServiceName, toServiceName, paramName]);
}

CFPH.Draw.removeConnection = function(outRect, inRect) {
	var connections = CFPH.Draw.connections;
	
	for (var i=0; i<connections.length; i++) {
		var outI = connections[i][3];
		var inI = connections[i][4];
		
		if (outI == outRect && inI == inRect) {
			var path = connections[i][5];
			path.remove();
			connections.splice(i, 1);
		}
	}
	
	CFPH.Draw.clearSelection();
	
	if (CFPH.Draw.listener)
		CFPH.Draw.listener.connectionRemoved(fromServiceName, toServiceName, paramName);
}

function inside(obj) {
	var s="";
	for (p in obj)
		s+=p+", "
	alert(s);
}

/*CFPH.Draw.setOffline = function(serviceName) {
	var service = CFPH.Draw.services[serviceName];

	var box = service.innerBox.getBBox();
	var x = box.x;
	var y = box.y;
	var width=box.width;
	var height=box.height;

	service.offline = CFPH.Draw.paper.set();
	service.offline.push(
		CFPH.Draw.paper.path("M"+x+" "+y+"L"+(x+width)+" "+(y+height)).attr({
			stroke:"red",
			"stroke-width":2
		}),
		CFPH.Draw.paper.path("M"+x+" "+(y+height)+"L"+(x+width)+" "+(y)).attr({
			stroke:"red",
			"stroke-width":2
		})
	);
	service.push(service.offline);
	
}*/

CFPH.Draw.setOnline = function(serviceName) {
	var service = CFPH.Draw.services[serviceName];
	if (service.offline)
		service.offline.remove();
}

CFPH.Draw.addService = function (x, y, serviceName, inputs, output, serviceObj, triggerFunction) { // int, int, str, array, bool, func
	var width  = 100;
	var height = 50;
	var ioWidth = 4;
	var ioHeight = 10;
	var paper = CFPH.Draw.paper;
	
	
	if (CFPH.Draw.services[serviceName])
		return;
	
	var set = paper.set();
	
	function hoverIn(e) {
		var circle = paper.circle(this.attrs["x"]+ioWidth/2, this.attrs["y"]+ioHeight/2, 10).attr({
			"stroke-width":2,
			stroke:"#c9dbf3"
		}).click(this.click);

		var text = paper.text(this.attrs["x"]+ioWidth/2, this.attrs["y"]-12, this.paramName).attr({
			"font-size":"12px",
		});
		this.surr = paper.set([circle, text]);
	}
	
	function hoverOut(e) {
		this.surr.remove();
	}

	//inputs
	for (var i=0; i<inputs.length; i++) {
		var inp = paper.rect(x+(width / inputs.length)*i+(width/inputs.length/2), y, ioWidth, ioHeight, 1).attr({
			"stroke-width":2,
			stroke:"red",
			fill:"red"
		});
		
		inp.paramName = inputs[i];
		inp.serviceObj = serviceObj;
		
		inp.click(function(e) {
			if (!CFPH.Draw.outSelected)
				return;
			
			var fromServiceName = CFPH.Draw.outSelected[0];
			var toServiceName = serviceName;
			var paramName = this.paramName;
			var outRect = CFPH.Draw.outSelected[1];
			var inRect = this;
			
			if (CFPH.Draw.connectionExists(outRect, inRect)) {
				CFPH.Draw.removeConnection(outRect, inRect);
			} else {
				CFPH.Draw.addConnection(fromServiceName, toServiceName, paramName, outRect, inRect, null);
			}
			CFPH.Draw.clearSelection();
			CFPH.Draw.update();
		});
		inp.hover(hoverIn, hoverOut);
		
		set.push(inp);
	}
	
	//output
	if (output) {
		var out = paper.rect(x + width/2, y+10+height, ioWidth, ioHeight, 1).attr({
			"stroke-width":2,
			stroke:"green",
			fill:"green"
		});
		
		out.click(function(e) {
			if (!CFPH.Draw.outSelected) {
				CFPH.Draw.setSelection(serviceName, out, null);

				out.attr({
					stroke:"blue",
					fill:"blue"
				});
			} else {
				CFPH.Draw.clearSelection();

				out.attr({
					stroke:"green",
					fill:"green"
				});
			}
		});
		
		out.serviceObj = serviceObj;
		out.hover(hoverIn, hoverOut);
		
		set.push(out);
	}
	
	//rect
	var rect = paper.rect(x,y+10,width,height,10).attr({
		"stroke-width":2,
		stroke:"black",
		fill:"white"
	});
	rect.dblclick(triggerFunction);
	var text = paper.text(x+width/2, y+10+height/2, serviceName).attr({
		"font-size":"12px"
	});
	
	set.push(rect);
	set.push(text);
		
	// set own properties on the set object
	set.innerBox = rect;
	set.inputs = inputs;
	set.serviceName = serviceName;
	
	// drag functionality
	function dragger(set) {
		return function(e) {
			for (var i=0; i<set.items.length; i++) {
				var t = set.items[i];
				if (t.type == "set") {
					dragger(t)(e);
				} if (t.type == "path") {
					inside(t.attrs);
					alert(t.attr("path"));
					//inside(t);
				} else {
					t.oldx = t.attr("x");
					t.oldy = t.attr("y");
				}
			}
		}
	}
	
	function move(dx, dy) {
		for (var i=0; i<set.items.length; i++) {
			var t = set.items[i];

			var att = ((t.type == "rect") || (t.type == "text")) ? {x: t.oldx + dx, y: t.oldy + dy} : {cx: t.oldx + dx, cy: t.oldy + dy};
			t.attr(att);
		}
		
		CFPH.Draw.update();
	}
	
	function up() { }
	
	set.drag(move, dragger(set), up);
	
	CFPH.Draw.services[serviceName] = set;
}

CFPH.Draw.update = function () {
	var paper = CFPH.Draw.paper;
	var connections = CFPH.Draw.connections;
	
	for (var i=0; i<connections.length; i++) {
		var fromServiceName = connections[i][0];
		var toServiceName = connections[i][1];
		var paramName = connections[i][2];
		var outRect = connections[i][3];
		var inRect = connections[i][4];
		var path = connections[i][5];
		
		if (path)
			path.remove();
		
		var fromX = outRect.attrs["x"]+2;
		var fromY = outRect.attrs["y"]+10;
		var toX = inRect.attrs["x"]+2;
		var toY = inRect.attrs["y"];
		
		path = paper.path("M"+fromX+" "+fromY+"L"+toX+" "+toY).attr({
			"stroke-width":2,
			stroke:"gray",
			"stroke-dasharray":"."
		});
		
		connections[i] = [fromServiceName, toServiceName, paramName, outRect, inRect, path];
	}
}

/*CFPH.Draw.onMouseMove = function(e) {
	if (!CFPH.Draw.outSelected)
		return;

	var serviceName = CFPH.Draw.outSelected[0];
	var outRect = CFPH.Draw.outSelected[1];
	var x = Math.round(outRect.attrs["x"]);
	var y = Math.round(outRect.attrs["y"]+outRect.attrs["height"]);
}*/

CFPH.Draw.clearSelection = function() {
	var rect = CFPH.Draw.outSelected[1];
	rect.attr({
		stroke:"green",
		fill:"green"
	});
	CFPH.Draw.outSelected = null;
//	document.body.onmousemove = null;
}

CFPH.Draw.setSelection = function(serviceName, rect, path) {
	CFPH.Draw.outSelected = [serviceName, rect, path];
//	document.body.onmousemove = CFPH.Draw.onMouseMove;
}


